{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "# How to pass tool outputs to chat models\n",
        "\n",
        "```{=mdx}\n",
        ":::info Prerequisites\n",
        "This guide assumes familiarity with the following concepts:\n",
        "\n",
        "- [LangChain Tools](/docs/concepts/tools)\n",
        "- [Tool calling](/docs/concepts/tool_calling)\n",
        "- [Using chat models to call tools](/docs/how_to/tool_calling)\n",
        "- [Defining custom tools](/docs/how_to/custom_tools/)\n",
        "\n",
        ":::\n",
        "```\n",
        "\n",
        "Some models are capable of [**tool calling**](/docs/concepts/tool_calling) - generating arguments that conform to a specific user-provided schema. This guide will demonstrate how to use those tool calls to actually call a function and properly pass the results back to the model.\n",
        "\n",
        "![](../../static/img/tool_invocation.png)\n",
        "\n",
        "![](../../static/img/tool_results.png)\n",
        "\n",
        "First, let's define our tools and our model:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "metadata": {},
      "outputs": [],
      "source": [
        "import { z } from \"zod\";\n",
        "import { tool } from \"@langchain/core/tools\";\n",
        "\n",
        "const addTool = tool(async ({ a, b }) => {\n",
        "  return a + b;\n",
        "}, {\n",
        "  name: \"add\",\n",
        "  schema: z.object({\n",
        "    a: z.number(),\n",
        "    b: z.number(),\n",
        "  }),\n",
        "  description: \"Adds a and b.\",\n",
        "});\n",
        "\n",
        "const multiplyTool = tool(async ({ a, b }) => {\n",
        "  return a * b;\n",
        "}, {\n",
        "  name: \"multiply\",\n",
        "  schema: z.object({\n",
        "    a: z.number(),\n",
        "    b: z.number(),\n",
        "  }),\n",
        "  description: \"Multiplies a and b.\",\n",
        "});\n",
        "\n",
        "const tools = [addTool, multiplyTool];"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "```{=mdx}\n",
        "import ChatModelTabs from \"@theme/ChatModelTabs\";\n",
        "\n",
        "<ChatModelTabs customVarName=\"llm\" />\n",
        "```"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Now, let's get the model to call a tool. We'll add it to a list of messages that we'll treat as conversation history:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "AIMessage {\n",
            "  \"id\": \"chatcmpl-9p1NbC7sfZP0FE0bNfFiVYbPuWivg\",\n",
            "  \"content\": \"\",\n",
            "  \"additional_kwargs\": {\n",
            "    \"tool_calls\": [\n",
            "      {\n",
            "        \"id\": \"call_RbUuLMYf3vgcdSQ8bhy1D5Ty\",\n",
            "        \"type\": \"function\",\n",
            "        \"function\": \"[Object]\"\n",
            "      },\n",
            "      {\n",
            "        \"id\": \"call_Bzz1qgQjTlQIHMcEaDAdoH8X\",\n",
            "        \"type\": \"function\",\n",
            "        \"function\": \"[Object]\"\n",
            "      }\n",
            "    ]\n",
            "  },\n",
            "  \"response_metadata\": {\n",
            "    \"tokenUsage\": {\n",
            "      \"completionTokens\": 50,\n",
            "      \"promptTokens\": 87,\n",
            "      \"totalTokens\": 137\n",
            "    },\n",
            "    \"finish_reason\": \"tool_calls\",\n",
            "    \"system_fingerprint\": \"fp_400f27fa1f\"\n",
            "  },\n",
            "  \"tool_calls\": [\n",
            "    {\n",
            "      \"name\": \"multiply\",\n",
            "      \"args\": {\n",
            "        \"a\": 3,\n",
            "        \"b\": 12\n",
            "      },\n",
            "      \"type\": \"tool_call\",\n",
            "      \"id\": \"call_RbUuLMYf3vgcdSQ8bhy1D5Ty\"\n",
            "    },\n",
            "    {\n",
            "      \"name\": \"add\",\n",
            "      \"args\": {\n",
            "        \"a\": 11,\n",
            "        \"b\": 49\n",
            "      },\n",
            "      \"type\": \"tool_call\",\n",
            "      \"id\": \"call_Bzz1qgQjTlQIHMcEaDAdoH8X\"\n",
            "    }\n",
            "  ],\n",
            "  \"invalid_tool_calls\": [],\n",
            "  \"usage_metadata\": {\n",
            "    \"input_tokens\": 87,\n",
            "    \"output_tokens\": 50,\n",
            "    \"total_tokens\": 137\n",
            "  }\n",
            "}\n",
            "2\n"
          ]
        }
      ],
      "source": [
        "import { HumanMessage } from \"@langchain/core/messages\";\n",
        "\n",
        "const llmWithTools = llm.bindTools(tools);\n",
        "\n",
        "const messages = [\n",
        "  new HumanMessage(\"What is 3 * 12? Also, what is 11 + 49?\"),\n",
        "];\n",
        "\n",
        "const aiMessage = await llmWithTools.invoke(messages);\n",
        "\n",
        "console.log(aiMessage);\n",
        "\n",
        "messages.push(aiMessage);"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Next let's invoke the tool functions using the args the model populated!\n",
        "\n",
        "Conveniently, if we invoke a LangChain `Tool` with a `ToolCall`, we'll automatically get back a `ToolMessage` that can be fed back to the model:\n",
        "\n",
        "```{=mdx}\n",
        ":::caution Compatibility\n",
        "\n",
        "This functionality requires `@langchain/core>=0.2.16`. Please see here for a [guide on upgrading](/docs/how_to/installation/#installing-integration-packages).\n",
        "\n",
        "If you are on earlier versions of `@langchain/core`, you will need to access construct a `ToolMessage` manually using fields from the tool call.\n",
        "\n",
        ":::\n",
        "```"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "[\n",
            "  HumanMessage {\n",
            "    \"content\": \"What is 3 * 12? Also, what is 11 + 49?\",\n",
            "    \"additional_kwargs\": {},\n",
            "    \"response_metadata\": {}\n",
            "  },\n",
            "  AIMessage {\n",
            "    \"id\": \"chatcmpl-9p1NbC7sfZP0FE0bNfFiVYbPuWivg\",\n",
            "    \"content\": \"\",\n",
            "    \"additional_kwargs\": {\n",
            "      \"tool_calls\": [\n",
            "        {\n",
            "          \"id\": \"call_RbUuLMYf3vgcdSQ8bhy1D5Ty\",\n",
            "          \"type\": \"function\",\n",
            "          \"function\": \"[Object]\"\n",
            "        },\n",
            "        {\n",
            "          \"id\": \"call_Bzz1qgQjTlQIHMcEaDAdoH8X\",\n",
            "          \"type\": \"function\",\n",
            "          \"function\": \"[Object]\"\n",
            "        }\n",
            "      ]\n",
            "    },\n",
            "    \"response_metadata\": {\n",
            "      \"tokenUsage\": {\n",
            "        \"completionTokens\": 50,\n",
            "        \"promptTokens\": 87,\n",
            "        \"totalTokens\": 137\n",
            "      },\n",
            "      \"finish_reason\": \"tool_calls\",\n",
            "      \"system_fingerprint\": \"fp_400f27fa1f\"\n",
            "    },\n",
            "    \"tool_calls\": [\n",
            "      {\n",
            "        \"name\": \"multiply\",\n",
            "        \"args\": {\n",
            "          \"a\": 3,\n",
            "          \"b\": 12\n",
            "        },\n",
            "        \"type\": \"tool_call\",\n",
            "        \"id\": \"call_RbUuLMYf3vgcdSQ8bhy1D5Ty\"\n",
            "      },\n",
            "      {\n",
            "        \"name\": \"add\",\n",
            "        \"args\": {\n",
            "          \"a\": 11,\n",
            "          \"b\": 49\n",
            "        },\n",
            "        \"type\": \"tool_call\",\n",
            "        \"id\": \"call_Bzz1qgQjTlQIHMcEaDAdoH8X\"\n",
            "      }\n",
            "    ],\n",
            "    \"invalid_tool_calls\": [],\n",
            "    \"usage_metadata\": {\n",
            "      \"input_tokens\": 87,\n",
            "      \"output_tokens\": 50,\n",
            "      \"total_tokens\": 137\n",
            "    }\n",
            "  },\n",
            "  ToolMessage {\n",
            "    \"content\": \"36\",\n",
            "    \"name\": \"multiply\",\n",
            "    \"additional_kwargs\": {},\n",
            "    \"response_metadata\": {},\n",
            "    \"tool_call_id\": \"call_RbUuLMYf3vgcdSQ8bhy1D5Ty\"\n",
            "  },\n",
            "  ToolMessage {\n",
            "    \"content\": \"60\",\n",
            "    \"name\": \"add\",\n",
            "    \"additional_kwargs\": {},\n",
            "    \"response_metadata\": {},\n",
            "    \"tool_call_id\": \"call_Bzz1qgQjTlQIHMcEaDAdoH8X\"\n",
            "  }\n",
            "]\n"
          ]
        }
      ],
      "source": [
        "const toolsByName = {\n",
        "  add: addTool,\n",
        "  multiply: multiplyTool,\n",
        "}\n",
        "\n",
        "for (const toolCall of aiMessage.tool_calls) {\n",
        "  const selectedTool = toolsByName[toolCall.name];\n",
        "  const toolMessage = await selectedTool.invoke(toolCall);\n",
        "  messages.push(toolMessage);\n",
        "}\n",
        "\n",
        "console.log(messages);"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "And finally, we'll invoke the model with the tool results. The model will use this information to generate a final answer to our original query:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "AIMessage {\n",
            "  \"id\": \"chatcmpl-9p1NttGpWjx1cQoVIDlMhumYq12Pe\",\n",
            "  \"content\": \"3 * 12 is 36, and 11 + 49 is 60.\",\n",
            "  \"additional_kwargs\": {},\n",
            "  \"response_metadata\": {\n",
            "    \"tokenUsage\": {\n",
            "      \"completionTokens\": 19,\n",
            "      \"promptTokens\": 153,\n",
            "      \"totalTokens\": 172\n",
            "    },\n",
            "    \"finish_reason\": \"stop\",\n",
            "    \"system_fingerprint\": \"fp_18cc0f1fa0\"\n",
            "  },\n",
            "  \"tool_calls\": [],\n",
            "  \"invalid_tool_calls\": [],\n",
            "  \"usage_metadata\": {\n",
            "    \"input_tokens\": 153,\n",
            "    \"output_tokens\": 19,\n",
            "    \"total_tokens\": 172\n",
            "  }\n",
            "}\n"
          ]
        }
      ],
      "source": [
        "await llmWithTools.invoke(messages);"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Note that each `ToolMessage` must include a `tool_call_id` that matches an `id` in the original tool calls that the model generates. This helps the model match tool responses with tool calls.\n",
        "\n",
        "Tool calling agents, like those in [LangGraph](https://langchain-ai.github.io/langgraphjs/tutorials/introduction/), use this basic flow to answer queries and solve tasks.\n",
        "\n",
        "## Related\n",
        "\n",
        "You've now seen how to pass tool calls back to a model.\n",
        "\n",
        "These guides may interest you next:\n",
        "\n",
        "- [LangGraph quickstart](https://langchain-ai.github.io/langgraphjs/tutorials/introduction/)\n",
        "- Few shot prompting [with tools](/docs/how_to/tools_few_shot/)\n",
        "- Stream [tool calls](/docs/how_to/tool_streaming/)\n",
        "- Pass [runtime values to tools](/docs/how_to/tool_runtime)\n",
        "- Getting [structured outputs](/docs/how_to/structured_output/) from models"
      ]
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "TypeScript",
      "language": "typescript",
      "name": "tslab"
    },
    "language_info": {
      "codemirror_mode": {
        "mode": "typescript",
        "name": "javascript",
        "typescript": true
      },
      "file_extension": ".ts",
      "mimetype": "text/typescript",
      "name": "typescript",
      "version": "3.7.2"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 4
}
